package dao.hibernate;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.collections.MultiMap;
import org.apache.commons.collections.iterators.EntrySetMapIterator;
import org.hibernate.Query;
import org.hibernate.Session;

import util.HibernateUtil;
import util.Util;
import dao.BenhDAO;
import model.Benh;
import model.ChuDe;
import model.LoaiBenh;

public class BenhDAOHibernate extends GenericHibernateDAO<Benh, Long> implements
		BenhDAO {
	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findAllBenhByIdLoaiBenh(long idLoaiBenh) {
		List<Benh> list = new ArrayList<Benh>();
		Query query = getSession().createQuery("SELECT benh.idChuDe, benh.tenChuDe, benh.chuDeCha, benh.loaiBenh FROM Benh AS benh WHERE benh.loaiBenh.idLoaiBenh = :pname ORDER BY benh.tenChuDe")
		.setLong("pname", idLoaiBenh);
		Iterator iter = query.list().iterator();
		Benh benh = null;
		while(iter.hasNext()){
			Object[] row = (Object[])iter.next();
			long idBenh = (Long)row[0];
			String tenBenh = (String)row[1];
			ChuDe chuDeCha = (ChuDe)row[2];
			LoaiBenh loaiBenh = (LoaiBenh)row[3];
			benh = new Benh(tenBenh, chuDeCha, loaiBenh, null, null, null, null, null, null);
			benh.setIdChuDe(idBenh);
			list.add(benh);
		}
		return list;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByTenBenhLike(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.tenChuDe LIKE :pname")
				.setString("pname", "%" + keyword + "%").list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByTenLoaiBenhLike(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.loaiBenh.tenLoaiBenh LIKE :pname")
				.setString("pname", "%" + keyword + "%").list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByNguyenNhanLike(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.nguyenNhan LIKE :pname")
				.setString("pname", "%" + keyword + "%").list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByTrieuChungLike(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.trieuChung LIKE :pname")
				.setString("pname", "%" + keyword + "%").list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByChanDoanLike(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.chanDoan LIKE :pname")
				.setString("pname", "%" + keyword + "%").list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByCachChuaTriTayYLike(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.cachChuaTriTayY LIKE :pname")
				.setString("pname", "%" + keyword + "%").list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByCachChuaTriDongYLike(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.cachChuaTriDongY LIKE :pname")
				.setString("pname", "%" + keyword + "%").list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByPhongChongBenhLike(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.phongChongBenh LIKE :pname")
				.setString("pname", "%" + keyword + "%").list();
	}

	@Override
	public List<Benh> findByOneCondition(String criteria, String keyWord) {
		List<Benh> list = new ArrayList<Benh>();
		if (criteria.equals("tenBenh")) {
			list = findByTenBenhLike(keyWord);
		} else if (criteria.equals("tenLoaiBenh")) {
			list = findByTenLoaiBenhLike(keyWord);
		} else if (criteria.equals("nguyenNhan")) {
			list = findByNguyenNhanLike(keyWord);
		} else if (criteria.equals("trieuChung")) {
			list = findByTrieuChungLike(keyWord);
		} else if (criteria.equals("chanDoan")) {
			list = findByChanDoanLike(keyWord);
		} else if (criteria.equals("cachChuaTriTayY")) {
			list = findByCachChuaTriTayYLike(keyWord);
		} else if (criteria.equals("cachChuaTriDongY")) {
			list = findByCachChuaTriDongYLike(keyWord);
		} else if (criteria.equals("phongChongBenh")) {
			list = findByPhongChongBenhLike(keyWord);
		} else if (criteria.equals("chuyenKhoa")) {
			list = findByChuyenKhoaLike(keyWord);
		}
		
		List<Benh> result = new ArrayList<Benh>();
		Benh benhSimple = null;
		for (Benh benh : list) {
			benhSimple = new Benh(benh.getTenChuDe(), benh.getChuDeCha(), benh.getLoaiBenh(), null, null, null, null, null, null);
			benhSimple.setIdChuDe(benh.getIdChuDe());
			result.add(benhSimple);
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByKeyword(String keyword) {
		return getSession()
				.createQuery(
						"FROM Benh AS benh WHERE benh.nguyenNhan = :pname OR "
								+ "benh.trieuChung = :pname OR "
								+ "benh.chanDoan = :pname OR "
								+ "benh.cachChuaTriTayY = :pname OR "
								+ "benh.cachChuaTriDongY = :pname OR "
								+ "benh.phongChongBenh = :pname OR ")
				.setString("pname", "%" + keyword + "%").list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByManyConditions(MultiMap conditions) {
		List<Benh> result = null;
		EntrySetMapIterator iterator = new EntrySetMapIterator(conditions);
		String criteria = "";
		List<String> keywords = new ArrayList<String>();
		String keyword = "";
		while (iterator.hasNext()) {
			criteria = (String) iterator.next();
			keywords = (ArrayList<String>) conditions.get(criteria);
			for (String k : keywords) {
				keyword = k;
				if (criteria.equals("tenBenh")) {
					List<Benh> list = findByTenBenhLike(keyword);
					result = Util.retainAllBenh(result, list);
				} else if (criteria.equals("nguyenNhan")) {
					List<Benh> list = findByNguyenNhanLike(keyword);
					result = Util.retainAllBenh(result, list);
				} else if (criteria.equals("trieuChung")) {
					List<Benh> list = findByTrieuChungLike(keyword);
					result = Util.retainAllBenh(result, list);
				} else if (criteria.equals("chanDoan")) {
					List<Benh> list = findByChanDoanLike(keyword);
					result = Util.retainAllBenh(result, list);
				} else if (criteria.equals("cachChuaTriTayY")) {
					List<Benh> list = findByCachChuaTriTayYLike(keyword);
					result = Util.retainAllBenh(result, list);
				} else if (criteria.equals("cachChuaTriDongY")) {
					List<Benh> list = findByCachChuaTriDongYLike(keyword);
					result = Util.retainAllBenh(result, list);
				} else if (criteria.equals("phongChongBenh")) {
					List<Benh> list = findByPhongChongBenhLike(keyword);
					result = Util.retainAllBenh(result, list);
				}
			}
		}
		return result;
	}
	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findAllTop30() {
		List<Benh> list = new ArrayList<Benh>();
		Query query = getSession().createQuery("SELECT benh.idChuDe, benh.tenChuDe, benh.chuDeCha, benh.loaiBenh FROM Benh AS benh ORDER BY benh.tenChuDe")
		.setFirstResult(0).setMaxResults(30);
		Iterator iter = query.list().iterator();
		Benh benh = null;
		while(iter.hasNext()){
			Object[] row = (Object[])iter.next();
			long idBenh = (Long)row[0];
			String tenBenh = (String)row[1];
			ChuDe chuDeCha = (ChuDe)row[2];
			LoaiBenh loaiBenh = (LoaiBenh)row[3];
			benh = new Benh(tenBenh, chuDeCha, loaiBenh, null, null, null, null, null, null);
			benh.setIdChuDe(idBenh);
			list.add(benh);
		}
		return list;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Benh> findByChuyenKhoaLike(String keyword) {
		List<Benh> list = new ArrayList<Benh>();
		Query query = getSession().createQuery("SELECT benh.idChuDe, benh.tenChuDe, benh.chuDeCha, benh.loaiBenh FROM Benh AS benh WHERE benh.loaiBenh.chuyenKhoa.tenChuyenKhoa LIKE :pname ORDER BY benh.tenChuDe")
		.setString("pname", "%" + keyword + "%");
		Iterator iter = query.list().iterator();
		Benh benh = null;
		while(iter.hasNext()){
			Object[] row = (Object[])iter.next();
			long idBenh = (Long)row[0];
			String tenBenh = (String)row[1];
			ChuDe chuDeCha = (ChuDe)row[2];
			LoaiBenh loaiBenh = (LoaiBenh)row[3];
			benh = new Benh(tenBenh, chuDeCha, loaiBenh, null, null, null, null, null, null);
			benh.setIdChuDe(idBenh);
			list.add(benh);
		}
		return list;
	}
	public static void main(String[] args) {
		Session session = HibernateUtil.getCurrentSession();
		session.beginTransaction();
		List<Benh> list = new BenhDAOHibernate().findByNguyenNhanLike("nguyên nhân gây bệnh gút");
		System.out.println(list.get(0).getTenChuDe());
		session.getTransaction().commit();
	}
}
